/**
 * Vue项目构建处理器
 * 处理与Vue项目构建相关的IPC请求
 */

const { ipcMain, app, shell } = require('electron');
const fs = require('fs');
const path = require('path');
const os = require('os');
const { spawn } = require('child_process');
const AdmZip = require('adm-zip');
const rimraf = require('rimraf');

// 临时目录
const tempDir = path.join(os.tmpdir(), 'easy-window-builder');
// 缓存目录
const cacheDir = path.join(app.getPath('userData'), 'npm-cache');
// 输出目录
const outputDir = path.join(app.getPath('downloads'), 'easy-window-builds');

// 确保目录存在
function ensureDir(dir) {
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
  return dir;
}

// 初始化目录
ensureDir(tempDir);
ensureDir(cacheDir);
ensureDir(outputDir);

/**
 * 运行命令
 * @param {string} command 命令
 * @param {string[]} args 参数
 * @param {Object} options 选项
 * @returns {Promise<{success: boolean, stdout: string, stderr: string}>} 结果
 */
function runCommand(command, args, options = {}) {
  return new Promise((resolve) => {
    // 重命名变量，避免与全局process冲突
    const childProc = spawn(command, args, {
      ...options,
      shell: true,
      env: { ...process.env, ...options.env }
    });
    
    let stdout = '';
    let stderr = '';
    
    childProc.stdout.on('data', (data) => {
      stdout += data.toString();
      options.onProgress && options.onProgress({ type: 'stdout', data: data.toString() });
    });
    
    childProc.stderr.on('data', (data) => {
      stderr += data.toString();
      options.onProgress && options.onProgress({ type: 'stderr', data: data.toString() });
    });
    
    childProc.on('close', (code) => {
      resolve({
        success: code === 0,
        stdout,
        stderr,
        code
      });
    });
  });
}

/**
 * 注册IPC处理程序
 */
function registerVueBuilderHandlers() {
  // 获取NPM缓存路径
  ipcMain.handle('get-npm-cache-path', async () => {
    try {
      return {
        success: true,
        path: cacheDir
      };
    } catch (error) {
      console.error('获取NPM缓存路径失败:', error);
      return {
        success: false,
        message: error.message
      };
    }
  });
  
  // 保存Blob到临时文件并可选解压
  ipcMain.handle('save-blob-to-temp', async (event, { blob, filename, extractAfterSave = false }) => {
    try {
      // 生成唯一ID (时间戳+随机数)
      const uniqueId = `${Date.now()}-${Math.floor(Math.random() * 10000)}`;
      
      // 创建项目目录
      const projectDir = path.join(tempDir, uniqueId);
      ensureDir(projectDir);
      
      // 保存文件路径
      const filePath = path.join(projectDir, filename);
      
      // 将ArrayBuffer转为Buffer并写入文件
      const buffer = Buffer.from(blob);
      fs.writeFileSync(filePath, buffer);
      
      // 如果需要解压
      let extractPath = null;
      if (extractAfterSave && (filename.endsWith('.zip'))) {
        console.log(`解压文件: ${filePath}`);
        
        // 解压路径
        extractPath = path.join(projectDir, 'extracted');
        ensureDir(extractPath);
        
        // 解压文件
        const zip = new AdmZip(filePath);
        zip.extractAllTo(extractPath, true);
        
        // 查找真正的项目目录（在压缩包内部可能有一层目录）
        const files = fs.readdirSync(extractPath);
        if (files.length === 1 && fs.statSync(path.join(extractPath, files[0])).isDirectory()) {
          // ZIP包含单个目录，使用它作为项目目录
          extractPath = path.join(extractPath, files[0]);
        }
        
        console.log(`文件解压完成，路径: ${extractPath}`);
      }
      
      return {
        success: true,
        filePath,
        projectDir,
        extractPath
      };
    } catch (error) {
      console.error('保存Blob到临时文件失败:', error);
      return {
        success: false,
        message: error.message
      };
    }
  });
  
  // 检查构建环境
  ipcMain.handle('check-build-environment', async () => {
    try {
      // 检查Node.js
      const nodeResult = await runCommand('node', ['--version']);
      if (!nodeResult.success) {
        return {
          success: false,
          message: '未检测到Node.js，请确保已安装Node.js'
        };
      }
      
      // 检查NPM
      const npmResult = await runCommand('npm', ['--version']);
      if (!npmResult.success) {
        return {
          success: false,
          message: '未检测到npm，请确保已安装npm'
        };
      }
      
      return {
        success: true,
        nodeVersion: nodeResult.stdout.trim(),
        npmVersion: npmResult.stdout.trim()
      };
    } catch (error) {
      console.error('检查构建环境失败:', error);
      return {
        success: false,
        message: error.message
      };
    }
  });
  
  // 构建Vue项目
  ipcMain.handle('build-vue-project', async (event, options) => {
    try {
      const {
        projectPath,
        useChineseRegistry = true,
        skipCache = false,
        buildMode = 'development',
        cachePath
      } = options;
      
      // 验证路径
      if (!fs.existsSync(projectPath)) {
        throw new Error(`项目路径不存在: ${projectPath}`);
      }
      
      // 进度报告
      const progressCallback = (progress) => {
        event.sender.send('build-progress', progress);
      };
      
      // 设置npm缓存
      const npmCacheDir = cachePath || cacheDir;
      const registry = useChineseRegistry ? 
        'https://registry.npmmirror.com' : 
        'https://registry.npmjs.org';
      
      // 设置npm选项
      const npmInstallOptions = [
        'install',
        '--no-audit',
        '--no-fund',
        '--no-progress',
        skipCache ? '--no-cache' : `--cache=${npmCacheDir}`,
        `--registry=${registry}`
      ];
      
      // 确保安装terser
      npmInstallOptions.push('terser@latest', '--save-dev');
      
      // 安装依赖
      progressCallback('正在准备NPM缓存...');
      await runCommand('npm', ['config', 'set', `cache=${npmCacheDir}`], {
        cwd: projectPath,
        onProgress: (data) => progressCallback(`配置NPM缓存: ${data.data}`)
      });
      
      progressCallback('正在安装依赖 (这可能需要几分钟)...');
      await runCommand('npm', npmInstallOptions, {
        cwd: projectPath,
        onProgress: (data) => progressCallback(`安装依赖: ${data.data}`)
      });
      
      // 构建项目
      progressCallback('正在构建项目...');
      await runCommand('npm', ['run', 'build'], {
        cwd: projectPath,
        onProgress: (data) => progressCallback(`构建: ${data.data}`)
      });
      
      // 构建输出目录
      const distDir = path.join(projectPath, 'dist');
      const outputDir = path.join(app.getPath('downloads'), 'easy-window-builds', path.basename(projectPath));
      
      // 确保输出目录存在
      ensureDir(outputDir);
      
      // 删除旧的输出目录内容
      rimraf.sync(path.join(outputDir, '*'));
      
      // 复制构建结果到输出目录
      fs.cpSync(distDir, outputDir, { recursive: true });
      
      progressCallback('构建完成！');
      
      return {
        success: true,
        message: '项目构建成功',
        outputPath: outputDir
      };
    } catch (error) {
      console.error('构建Vue项目失败:', error);
      return {
        success: false,
        message: `构建项目失败: ${error.message}`
      };
    }
  });
  
  // 打开文件夹
  ipcMain.handle('open-build-output-folder', async (event, folderPath) => {
    try {
      // 确保路径存在
      if (!fs.existsSync(folderPath)) {
        throw new Error(`路径不存在: ${folderPath}`);
      }
      
      // 打开文件夹
      await shell.openPath(folderPath);
      
      return {
        success: true
      };
    } catch (error) {
      console.error('打开文件夹失败:', error);
      return {
        success: false,
        message: error.message
      };
    }
  });
  
  // 清理临时文件
  ipcMain.handle('clean-temp-files', async () => {
    try {
      // 获取临时目录中的所有内容
      const files = fs.readdirSync(tempDir);
      
      // 删除超过24小时的临时文件和目录
      const now = Date.now();
      let deletedCount = 0;
      
      for (const file of files) {
        const filePath = path.join(tempDir, file);
        const stats = fs.statSync(filePath);
        
        // 如果文件/目录超过24小时
        if (now - stats.mtimeMs > 24 * 60 * 60 * 1000) {
          if (stats.isDirectory()) {
            rimraf.sync(filePath);
          } else {
            fs.unlinkSync(filePath);
          }
          deletedCount++;
        }
      }
      
      return {
        success: true,
        message: `清理了${deletedCount}个临时文件/目录`
      };
    } catch (error) {
      console.error('清理临时文件失败:', error);
      return {
        success: false,
        message: error.message
      };
    }
  });
}

module.exports = {
  registerVueBuilderHandlers
}; 